//
//  DNKTcpRequestManager.m
//  XiangJia
//
//  Created by user on 16/7/26.
//  Copyright © 2016年 Dnake. All rights reserved.
//

#import "DNKTcpRequestManager.h"
#import "GCDAsyncSocket.h"

@interface DNKTcpRequestManager ()<GCDAsyncSocketDelegate>

@property (strong, nonatomic) dispatch_queue_t socketQueue;// 发数据的串行队列

@property (nonatomic, assign) BOOL isSuccess;//判断网关是否有数据返回

@end

@implementation DNKTcpRequestManager
{
    GCDAsyncSocket *tcpSocket;
    NSInteger index;
}

#pragma mark - 单例模式创建socket
+ (DNKTcpRequestManager *)shareTcpManager
{
    static DNKTcpRequestManager *manager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[DNKTcpRequestManager alloc] init];
    });
    return manager;
}

- (instancetype)init
{
    if (self = [super init]) {
        [self resetSocket];
    }
    return self;
}

- (dispatch_queue_t)socketQueue {
    if (_socketQueue == nil) { 
        _socketQueue = dispatch_queue_create("com.sendSocket", DISPATCH_QUEUE_SERIAL);
    }
    return _socketQueue;
}

- (void)resetSocket
{
    [self disConnect];
    
    tcpSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:self.socketQueue];
//    tcpSocket.IPv6Enabled = false;
//    tcpSocket.IPv4Enabled = true;
    
    _isSuccess = NO;
}

- (void)disConnect {
    if (![tcpSocket isDisconnected]) {
        [tcpSocket disconnect];
    }
    tcpSocket = nil;
    self.socketQueue = nil;
}

- (BOOL)initWithPort:(NSInteger)port toIp:(NSString *)ip
{
    [self resetSocket];
    NSError* err = nil;
    [tcpSocket acceptOnPort:port error:&err];
    BOOL tcpRet = [tcpSocket connectToHost:ip onPort:port withTimeout:2.0 error:&err];
    if (!tcpRet) {
        NSLog(@"TCP连接端口错误：%@",err.localizedDescription);
    } 
    return tcpRet;
}

/**
 发送控制命名
 */
- (void)controllStripWithData:(NSData *)data
{
    _isSuccess = NO;
    dispatch_async(dispatch_get_main_queue(), ^{
        [tcpSocket writeData:data withTimeout:self.deplyTime tag:1];
    });
    
}

#pragma mark - 代理方法表示连接成功
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
    //链接成功后再发送数据
    dispatch_async(dispatch_get_main_queue(), ^{
        _isSuccess = NO;
        [tcpSocket readDataWithTimeout:self.deplyTime tag:1];
    });
}

-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    NSLog(@"TCP - Socket - 连接错误 - %@",err.localizedDescription);
    
    if (_isSuccess) {
        return;
    }
    if (err) {
        [self timeoutControl];
    }
}

#pragma mark - 超时就会调用这个方法
- (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag
                 elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length
{
    NSLog(@"TCP - socket - TimeoutRead - 请求超时:%f",elapsed);
    [self timeoutControl];
    return elapsed;
}

- (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag
                 elapsed:(NSTimeInterval)elapsed
               bytesDone:(NSUInteger)length
{
    NSLog(@"TCP - socket - TimeoutWrite - 请求超时:%f",elapsed);
    [self timeoutControl];
    return elapsed;
}

#pragma mark - 消息发送成功 代理函数
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    
    _isSuccess = NO;
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [tcpSocket readDataWithTimeout:self.readTimeout tag:tag];
    });
    
}

//接受消息成功之后回调
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    dispatch_async(dispatch_get_main_queue(), ^{
        _isSuccess = YES; 
        [tcpSocket readDataWithTimeout:self.readTimeout tag:1];
        if (self.zSocketBlock) {
            self.zSocketBlock(data);
        }
        if (self.zSocketFailureBlock) {
            self.zSocketFailureBlock(nil);
        }
        
    });
    
}

-(void)returnData:(SocketBlock)block failure:(SocketFailureBlock)failureBlock {
    self.zSocketBlock = block;
    self.zSocketFailureBlock = failureBlock;
}

/**
 *  超时处理
 */
-(void)timeoutControl
{
    if (self.zSocketBlock) {
        self.zSocketBlock(nil);
    }
    if (self.zSocketFailureBlock) {
        self.zSocketFailureBlock(@"TimeOut");
    } 
    
}




@end
